package com.dreamlin.app.common

import android.content.Context
import android.content.Intent
import android.content.res.Resources
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.drawable.Drawable
import android.net.Uri
import android.os.SystemClock
import android.text.TextUtils
import android.util.Log
import android.util.TypedValue
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.dreamlin.app.App
import com.dreamlin.app.BuildConfig
import me.jessyan.autosize.AutoSizeConfig
import java.text.DateFormat
import java.text.ParseException
import java.text.SimpleDateFormat
import java.util.*
import java.util.concurrent.TimeUnit
import java.util.regex.Pattern
import kotlin.math.abs
import kotlin.math.pow

fun drawable2Bitmap(drawable: Drawable, width: Int = 0, height: Int = 0): Bitmap {
    val bitmap = Bitmap.createBitmap(
        if (width == 0) drawable.intrinsicWidth else width,
        if (height == 0) drawable.intrinsicHeight else height, Bitmap.Config.ARGB_8888
    )
    val canvas = Canvas(bitmap)
    drawable.setBounds(0, 0, bitmap.width, bitmap.height)
    drawable.draw(canvas)
    return bitmap
}

private val displayMetrics = Resources.getSystem().displayMetrics

/**
 * 获取屏幕宽
 *
 * @return
 */
fun getScreenWidth(): Int {
    return displayMetrics.widthPixels
}

/**
 * 获取屏幕高度
 *
 * @return
 */
fun getScreenHeight(): Int {
    return displayMetrics.heightPixels
}

fun Float.dp2px(): Float {
    val designWidthInDp = AutoSizeConfig.getInstance().designWidthInDp
    val initScreenWidthDp = AutoSizeConfig.getInstance().initScreenWidthDp
    return TypedValue.applyDimension(
        TypedValue.COMPLEX_UNIT_DIP,
        this,
        displayMetrics
    ) * initScreenWidthDp.toFloat() / designWidthInDp.toFloat()
}

fun Float.sp2px(): Float {
    val designWidthInDp = AutoSizeConfig.getInstance().designWidthInDp
    val initScreenWidthDp = AutoSizeConfig.getInstance().initScreenWidthDp
    return TypedValue.applyDimension(
        TypedValue.COMPLEX_UNIT_SP,
        this,
        displayMetrics
    ) * initScreenWidthDp.toFloat() / designWidthInDp.toFloat()
}


fun Float.px2dp(): Float =
    TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, this, displayMetrics)

fun jump(activity: AppCompatActivity, cls: Class<*>, requestCode: Int) {
    jump(activity, cls, requestCode, "")
}

fun jump(context: Context, cls: Class<*>) {
    jump(context, cls, "")
}

fun jump(context: Context, cls: Class<*>, title: String) {
    jump(context, cls, title, 0, null)
}

fun jump(
    context: Context,
    cls: Class<*>,
    title: String? = null,
    flag: Int = 0,
    content: String? = null
) {
    val intent = Intent(context, cls)
    if (!title.isNullOrEmpty()) {
        intent.putExtra("TITLE", title)
    }
    intent.putExtra("FLAG", flag)
    if (!content.isNullOrEmpty()) {
        intent.putExtra("CONTENT", content)
    }

    context.startActivity(intent)
}

fun jump(activity: AppCompatActivity, cls: Class<*>, requestCode: Int, title: String) {
    val intent = Intent(activity, cls)
    intent.putExtra("TITLE", title)
    activity.startActivityForResult(intent, requestCode)
}

private const val DEFAULT_TIME_INTERVAL: Long = 800
private const val TAG = "AntiShakeClickUtil"

/**
 * 最近一次点击的时间
 */
private var mLastClickTime: Long = 0

/**
 * 最近一次点击的控件ID
 */
private var mLastClickViewId = 0

fun isFastDoubleClick(clickedId: Int): Boolean {
    return isFastDoubleClick(
        clickedId,
        DEFAULT_TIME_INTERVAL
    )
}

/**
 * 是否是快速点击
 *
 * @param clickedId      点击的控件id
 * @param intervalMillis 时间间期（毫秒）
 * @return true:是，false:不是
 */
fun isFastDoubleClick(clickedId: Int, intervalMillis: Long): Boolean {
    val time = SystemClock.elapsedRealtime()
    val timeInterval = abs(time - mLastClickTime)
    return if (clickedId == mLastClickViewId && timeInterval < intervalMillis) {
        if (BuildConfig.DEBUG) {
            Log.d(TAG, "isFastDoubleClick:true ")
        }
        true
    } else {
        mLastClickTime = time
        mLastClickViewId = clickedId
        if (BuildConfig.DEBUG) {
            Log.d(TAG, "isFastDoubleClick: false")
        }
        false
    }
}

/**
 * 国内三家运营商的号段分别如下：
 * 电信号段:133/149/153/173/177/180/181/189/；
 * 联通号段:130/131/132/155/156/185/186/145/176；
 * 移动号段：134/135/136/137/138/139/150/151/152/157/158/159/182/183/184/187/188/147/178。
 * 手机号判断正则"^((17[0-9])(14[0-9])|(13[0-9])|(15[^4,\\D])|(18[0,5-9]))\\d{8}$"
 */
const val REGEX_MOBILE =
    "^((13[0-9])|(14[5-9])|(15[^4])|(16[5-7])|(17[0-8])|(18[0-9])|(19[1,8-9])|)\\d{8}$"

/**
 * 座机号码正则
 */

const val REGEX_LANDLINE = "^(0?(([1-9]\\d)|([3-9]\\d{2}))-?)?\\d{7,8}$"

/**
 * 密码正则
 */
const val REGEX_PASSWORD = "^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,20}$"

/**
 * 隧道位置桩号正则
 */
const val REGEX_K_POSITION = "^(K|k|YK|yk|ZK|zk)\\d{1,5}\\+\\d{1,3}$"

fun isTunnelPosition(position: String?): Boolean {
    return if (position.isNullOrEmpty()) false else Pattern.matches(REGEX_K_POSITION, position)
}

/**
 * 校验手机号
 *
 * @param phone
 * @return
 */
fun isPhoneNum(phone: String?): Boolean {
    return if (phone.isNullOrEmpty()) false else Pattern.matches(REGEX_MOBILE, phone)
}

fun isLandline(number: String?): Boolean {
    return Pattern.matches(REGEX_LANDLINE, number)
}

fun isPassword(password: String?): Boolean {
    return Pattern.matches(REGEX_PASSWORD, password)
}

fun callPhone(context: Context, phone: String) {
    var phone = phone
    phone = phone.trim { it <= ' ' }
    if (TextUtils.isEmpty(phone)) {
        Toast.makeText(context, "电话号码为空，无法拨打!", Toast.LENGTH_SHORT).show()
        return
    }
    phone = phone.replace("-", "")
    if (!isPhoneNum(phone) && !isLandline(
            phone
        )
    ) {
        Toast.makeText(context, "电话号码格式有误，请查证后再拨!", Toast.LENGTH_SHORT).show()
        return
    }
    val intent = Intent(Intent.ACTION_DIAL)
    val callData = Uri.parse("tel:$phone")
    intent.data = callData
    context.startActivity(intent)
}

fun callPhoneWithoutCheck(context: Context, phone: String) {
    var phone = phone
    phone = phone.trim { it <= ' ' }
    if (TextUtils.isEmpty(phone)) {
        Toast.makeText(context, "电话号码为空，无法拨打!", Toast.LENGTH_SHORT).show()
        return
    }
    phone = phone.replace("-", "")
    val intent = Intent(Intent.ACTION_DIAL)
    val callData = Uri.parse("tel:$phone")
    intent.data = callData
    context.startActivity(intent)
}

fun Stamp2Local(stamp: String): String? {
    val timeStamp = stamp.toLong() * 1000L
    val simpleDateFormat =
        SimpleDateFormat("yyyy-MM-dd HH:mm")
    val date = Date(timeStamp)
    return simpleDateFormat.format(date)
}

fun Stamp2Local(stamp: Long): String? {
    val simpleDateFormat =
        SimpleDateFormat("yyyy-MM-dd HH:mm")
    val date = Date(stamp)
    return simpleDateFormat.format(date)
}

fun Stamp2Local(stamp: Long, format: String?): String? {
    val simpleDateFormat = SimpleDateFormat(format)
    val date = Date(stamp)
    return simpleDateFormat.format(date)
}

@Throws(ParseException::class)
fun Time2Stamp(s: String?): Long {
    return Time2Stamp(s, "yyyy-MM-dd HH:mm:ss")
}

@Throws(ParseException::class)
fun Time2Stamp(time: String?, format: String?): Long {
    val simpleDateFormat = SimpleDateFormat(format)
    val date = simpleDateFormat.parse(time)
    return date.time
}

fun getStartTime(): Date? {
    val todayStart = Calendar.getInstance()
    todayStart[Calendar.HOUR_OF_DAY] = 0
    todayStart[Calendar.MINUTE] = 0
    todayStart[Calendar.SECOND] = 0
    todayStart[Calendar.MILLISECOND] = 0
    return todayStart.time
}

fun getnowEndTime(): Date? {
    val todayEnd = Calendar.getInstance()
    todayEnd[Calendar.HOUR_OF_DAY] = 23
    todayEnd[Calendar.MINUTE] = 59
    todayEnd[Calendar.SECOND] = 59
    todayEnd[Calendar.MILLISECOND] = 999
    return todayEnd.time
}

fun getYesterdayStartTime(): Date? {
    val yesterdayStart = Calendar.getInstance()
    yesterdayStart.add(Calendar.DATE, -1)
    yesterdayStart[Calendar.HOUR_OF_DAY] = 0
    yesterdayStart[Calendar.MINUTE] = 0
    yesterdayStart[Calendar.SECOND] = 0
    yesterdayStart[Calendar.MILLISECOND] = 0
    return yesterdayStart.time
}

fun getYear(time: Long): Int {
    val date = Date(time)
    val dateFormat = SimpleDateFormat("yyyy")
    val format = dateFormat.format(date)
    return format.toInt()
}

/**
 * @param curTime      当前时间
 * @param timeInterval 间隔时间,minute
 * @return
 */
fun generateNextTime(
    curTime: String?,
    timeInterval: Int,
    timeUnit: TimeUnit
): String? {
    var interval: Long = 0 //30分钟支付时间
    when {
        timeUnit === TimeUnit.DAYS -> {
            interval = timeInterval * 24 * 60 * 60 * 1000.toLong()
        }
        timeUnit === TimeUnit.HOURS -> {
            interval = timeInterval * 60 * 60 * 1000.toLong()
        }
        timeUnit === TimeUnit.MINUTES -> {
            interval = timeInterval * 60 * 1000.toLong()
        }
        timeUnit === TimeUnit.MILLISECONDS -> {
            interval = timeInterval * 1000.toLong()
        }
        timeUnit === TimeUnit.MICROSECONDS -> {
            interval = timeInterval / 1000.toLong()
        }
    }
    var endTime = curTime
    try {
        val parse = DateFormat.getInstance().parse(curTime)
        val endStamp = parse.time + interval
        parse.time = endStamp
        val dateFormat =
            SimpleDateFormat("yyyy年MM月dd日HH:mm:ss")
        endTime = dateFormat.format(parse)
    } catch (e: ParseException) {
        e.printStackTrace()
    } finally {
        return endTime
    }
}

fun generateNextTime(
    curTime: Long,
    timeInterval: Int,
    timeUnit: TimeUnit
): String? {
    var interval: Long = 0 //30分钟支付时间
    when {
        timeUnit === TimeUnit.DAYS -> {
            interval = timeInterval * 24 * 60 * 60 * 1000.toLong()
        }
        timeUnit === TimeUnit.HOURS -> {
            interval = timeInterval * 60 * 60 * 1000.toLong()
        }
        timeUnit === TimeUnit.MINUTES -> {
            interval = timeInterval * 60 * 1000.toLong()
        }
        timeUnit === TimeUnit.MILLISECONDS -> {
            interval = timeInterval * 1000.toLong()
        }
        timeUnit === TimeUnit.MICROSECONDS -> {
            interval = timeInterval / 1000.toLong()
        }
    }
    var endTime = ""
    val endStamp = curTime + interval
    val parse = Date(endStamp)
    val dateFormat = SimpleDateFormat("yyyy年MM月dd日HH:mm:ss")
    endTime = dateFormat.format(parse)
    return endTime
}

var HM = SimpleDateFormat("HH:mm")
var HMS = SimpleDateFormat("HH:mm:ss")

fun getHoursMinutes(stamp: Long): String? {
    return HM.format(Date(stamp))
}

fun getHMS(stamp: Long): String {
    return HMS.format(Date(stamp))
}

var MSHM = SimpleDateFormat("MM.dd HH:mm")

fun getMSHM(stamp: Long): String? {
    return MSHM.format(Date(stamp))
}

fun number2Chinese(number: Int): String {
    val chineseNumbers = arrayOf("零", "一", "二", "三", "四", "五", "六", "七", "八", "九")
    val chineseDigits = arrayOf("", "十", "百", "千", "万", "十", "百", "千", "亿")
    val numberStr = number.toString()
    val sb: StringBuilder = java.lang.StringBuilder()
    var dividend = number
    for (i in numberStr.length - 1 downTo 0) {
        val divisor = 10.0.pow(i).toInt()
        val index = dividend / divisor
        sb.append(chineseNumbers[index])
        /*if (index == 0) {
            if (i > 0) {
                sb.replace(Regex("零零"),"零")
                if (i == 4) {
                    sb.replace(sb.length-1, sb.length,chineseDigits[i])
                }
            }
        } else */
        sb.append(chineseDigits[i])
        dividend %= divisor
    }
    return sb.trimEnd('零').toString()
}

private const val SP_KEY = "tunnel_share_data"
const val USER_ACCOUNT = "userAccount"
const val TRANSITION_X = "floatTransitionX"
const val TRANSITION_Y = "floatTransitionY"

fun getStringData(key: String): String? {
    val sharedPreferences = App.appContext.getSharedPreferences(SP_KEY, Context.MODE_PRIVATE)
    return sharedPreferences.getString(key, null)
}

fun getFloatData(key: String): Float {
    val sharedPreferences = App.appContext.getSharedPreferences(SP_KEY, Context.MODE_PRIVATE)
    return sharedPreferences.getFloat(key, -1f)
}

fun writeStringData(key: String, value: Any) {
    val editor =
        App.appContext.getSharedPreferences(SP_KEY, Context.MODE_PRIVATE).edit()
    when (value) {
        is String -> {
            editor.putString(key, value)
            editor.apply()
        }
        is Int -> {
            editor.putInt(key, value)
            editor.apply()
        }
        is Boolean -> {
            editor.putBoolean(key, value)
            editor.apply()
        }
        is Float -> {
            editor.putFloat(key, value)
            editor.apply()
        }
        is Long -> {
            editor.putLong(key, value)
            editor.apply()
        }
    }
}